package supermarket;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.logging.LogFactory;

import com.gargoylesoftware.htmlunit.WebClient;

public abstract class ProductScraper <Page,ProductType,LinkType>{
	private ProductManager manager;
	private String marketURL;
	private final String configFile = "app.properties";
	
	private final WebClient webClient = new WebClient();
	
	public ProductScraper(ProductManager manager){
		setManager(manager);
		readMarketURL(getDistributor());
	}

	public ProductManager getManager() {
		return manager;
	}

	public void setManager(ProductManager manager) {
		this.manager = manager;
	}
	
	private void readMarketURL(Distributor distributor){
		Properties prop = new Properties();
	    InputStream is = null;
		try {
			is = new FileInputStream(getConfigFile());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	    try {
			prop.load(is);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//		System.out.println(prop.getProperty("app.url." + distributor.toString()));
		setMarketURL(prop.getProperty("app.url." + distributor.toString()));
	}
	
	public void scrape(){
		initializeScraper();
		
		getProductCategories(goToInitialPage());
		
		while(hasNextProductCategory()){
			Page page = processProductCategory(getNextProductCategory());
			
			getScrapeLinks(page);
			
			while(hasNextScrapeLinks()){
				scrapeLink(getNextScrapeLink());
			}
		}

	}
	protected abstract void getScrapeLinks(Page page);
	
	//Object nog vervangen door generic!! ook bij processProductCategory
	protected abstract Object getNextProductCategory();

	protected abstract boolean hasNextProductCategory();

	private void initializeScraper(){
		LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); 

	}
	
	protected abstract Page goToInitialPage();
	
	public abstract void getProductCategories(Page page);
	public abstract Page processProductCategory(Object category);
	
	public void scrapePage(Page page){
		getProducts(page);
		while(hasNextProduct()){
			scrapeProduct(getNextProduct());
		}
	}
	
	protected abstract void getProducts(Page page);

	public abstract boolean hasNextScrapeLinks();
	
	public abstract LinkType getNextScrapeLink();
	
	public abstract void scrapeLink(LinkType link);
	
	public abstract void scrapeProduct(ProductType product);
	
	public abstract boolean hasNextProduct();
	
	public abstract ProductType getNextProduct();

	public abstract Distributor getDistributor();
	
	public String getConfigFile() {
		return configFile;
	}

	public void setMarketURL(String marketURL) {
		this.marketURL = marketURL;
	}

	public String getMarketURL() {
		return marketURL;
	}

	public WebClient getWebClient() {
		return webClient;
	}
	
}
